package scg.utils.policies.loadbalancer;

import java.util.ArrayList;

import org.gridgain.grid.GridFactory;
import org.gridgain.grid.GridNode;

/**Implementación de la clase {@link BalancerPolicy} que define un orden round robin
 * para el mapeo de tareas terminales a nodos del grid*/
public class RoundRobinBalancerPolicy extends BalancerPolicy {

	
	private static int nextNode = -1;
		
	/**@param nodos pertenecientes al grid
	 * @return nodos del grid ordenados de menor a mayor en base a su dirección ip*/
	private static ArrayList<GridNode> sortNodes(ArrayList<GridNode> nodes) {
			
			ArrayList<GridNode> retorno = new ArrayList<GridNode>();
			if (nodes.size()== 0)
				return null;
			
			retorno.add(nodes.get(0));
								
			for (int i=1; i < nodes.size(); i++) {
				   boolean ready = false; 
				   String ip1 = nodes.get(i).getPhysicalAddress().substring(nodes.get(i).getPhysicalAddress().lastIndexOf(".")+1);
				   int ipNumber1 = Integer.parseInt(ip1);
				   for (int j=0; j < retorno.size() && !ready; j++){
				    String ip2 = retorno.get(j).getPhysicalAddress().substring(retorno.get(j).getPhysicalAddress().lastIndexOf(".")+1);
				    int ipNumber2 = Integer.parseInt(ip2);
				    if (ipNumber1 < ipNumber2){
				    	retorno.add(j, nodes.get(i));
				    	ready = true;
				    }			    
				  }
				  if (ready == false)
				     retorno.add(retorno.size(), nodes.get(i));   
			}
			
			return retorno;
	}
	

	/**@param limit
	 * 			cantidad total de nodos del grid
	 * @return entero que representa el indice del arreglo de nodos ordenados por ip donde se halla
	 * el próximo nodo donde será mapeada la siguiente tarea */
	private static synchronized int getNextNode(int limit){
		nextNode++;
		if (nextNode == limit)
			nextNode = 0;
		return nextNode;
	}
	
	
	/**{@inheritDoc}*/
	public GridNode getBalancedNode() {
		ArrayList<GridNode> nodes = sortNodes(new ArrayList<GridNode>(GridFactory.getGrid().getAllNodes()));
		
		return nodes.get(getNextNode(nodes.size()));
	}

}
